﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.Windows.Forms;
using NetJsWire.JsonRpcHandler;
using NetJsWire.JsonRpcHandler.Attributes;
using NetJsWire.Util;
using NetJsWire.Widgets.Core;
using NetJsWire.Widgets.Data;
using NetJsWire.Widgets.Renderers.Core;
using NetJsWire.Widgets.Ui.Form;
using NetJsWire.Widgets.Ui.Layout;

namespace NetJsWire.Widgets.Renderers.Form
{
    [ClassName( "Ext.form.FormPanel" )]
    internal class FormPanel : Widget, IRenderer
    {
        protected string _FORMPOSTED = string.Empty;
        private bool _eventAdded;

        public FormPanel( object baseObject )
            : base( baseObject )
        {
        }

        #region IRenderer Members

        public override void Render()
        {
            if ( !_eventAdded )
            {
                ( Base as Ui.Form.FormPanel ).form_post += FormPanelFormPost;
                _eventAdded = true;
            }

            if ( !Rendered )
            {
                if ( BaseParent is IWidgetContainer )
                {
                    SetAttribute( ControlNode, "isInContainer", true );
                    SetConstructionProperty( "isInContainer", true );

                    SetConstructionProperty( "x", ( ( Control ) Base ).Left );
                    SetConstructionProperty( "y", ( ( Control ) Base ).Top );
                }
                else
                {
                    SetStyleProperty( "position", "absolute" );
                    SetConstructionProperty( "renderTo", ClientParentToRender );
                }
                
                Plugins.Add( "new Ext.ux.OOSubmit()" );
                //SetConstructionProperty( "plugins", "[new Ext.ux.OOSubmit()]" );

                EnsureParentNodePosition();

                SetAttribute( "isContainer", true );
                Base.ConfigOptions.BaseParams.Add( new BaseParam( "service", "form_service" ) );
                Base.ConfigOptions.BaseParams.Add( new BaseParam( "method", "form_post" ) );
                Base.ConfigOptions.BaseParams.Add( new BaseParam( "id", InternalID ) );

                if ( Base.AutoHeight )
                {
                    SetConstructionProperty( "autoHeight", true );
                }
                else
                {
                    SetConstructionProperty( "autoHeight", false );
                    SetConstructionProperty( "height", Base.Height );
                }

                SetConstructionProperty( "width", Base.Width );

                if ( Base.Frame )
                    SetConstructionProperty( "frame", true );

                if ( !string.IsNullOrEmpty( Base.BodyStyle ) )
                    SetConstructionProperty( "bodyStyle", Base.BodyStyle );

                if ( Base.LabelWidth != 100 )
                    SetConstructionProperty( "labelWidth", Base.LabelWidth );

                if ( Base.LabelAlign != LabelAlign.Left )
                    SetConstructionProperty( "labelAlign", Base.LabelAlign.ToString().ToLower() );

                if ( !string.IsNullOrEmpty( Base.Defaults ) )
                    SetConstructionProperty( "defaults", Base.Defaults );

                if ( Base.MonitorValid )
                    SetConstructionProperty( "monitorValid", true );

                if ( Base.Layout != LayoutType.Form )
                    SetConstructionProperty( "layout", Base.Layout.ToString().ToLower() );

                if ( Base.FileUpload )
                {
                    SetConstructionProperty( "fileUpload", true );
                    SetConstructionProperty( "url", "webapp/" + ClientID + ".ashx" );
                }

                if ( !string.IsNullOrEmpty( Base.LabelSeparator ) && Base.LabelSeparator != ":" )
                    SetConstructionProperty( "labelSeparator", Base.LabelSeparator );

                if ( !string.IsNullOrEmpty( Base.ClientItems ) )
                {
                    var nodeItem = ControlNode.AppendChild( WebApplication.Instance.XmlDocument.CreateNode( "element", "clientItems", "" ) );
                    nodeItem.InnerText = Base.ClientItems;
                }
            }

            base.Render();
        }

        #endregion

        private void FormPanelFormPost( object sender, FormPostedEventArgs e )
        {
            var data = e.FormValues;

            foreach ( var item in data )
            {
                var key = item.Key;
                var value = item.Value;

                if ( key.StartsWith( "radio_" ) )
                {
                    key = item.Value.Split( ',' )[ 0 ];
                    value = item.Value.Split( ',' )[ 1 ];
                }
                else if ( key.StartsWith( "__hid__" ) )
                {
                    key = key.Replace( "__hid__", "" );
                }

                // This can happen if you manually add fields to the form via Javascript.
                if ( !WebApplication.Instance.Objects.ContainsKey( key ) )
                    continue;

                dynamic ctrl = WebApplication.Instance.Objects[ key ];

                if ( ctrl is Ui.Form.NumberField )
                {
                    ctrl.InternalChange = true;
                    ctrl.IsValid = true;
                    if ( ctrl.Text != item.Value )
                        ctrl.Text = item.Value;
                    ctrl.InternalChange = false;
                }
                else if ( ctrl is Ui.Form.TextField )
                {
                    ctrl.InternalChange = true;
                    ctrl.IsValid = true;
                    if ( item.Value != ctrl.Text )
                        ctrl.Text = item.Value;
                    ctrl.InternalChange = false;
                }
                else if ( ctrl is Ui.Form.DateField )
                {
                    ctrl.InternalChange = true;
                    ctrl.IsValid = true;
                    if ( ctrl.Text != item.Value )
                        ctrl.Text = item.Value;
                    ctrl.InternalChange = false;
                }
                else if ( ctrl is Ui.Form.ComboBox )
                {
                    ctrl.InternalChange = true;
                    ctrl.FromFormPost = true;
                    var _index = Convert.ToInt32( !string.IsNullOrEmpty( item.Value ) ? item.Value : "-1" );
                    if ( _index != ctrl.SelectedIndex )
                        ctrl.SelectedIndex = _index;
                    else
                        ctrl.FromFormPost = false;
                    ctrl.InternalChange = false;
                }
                else if ( ctrl is Ui.Form.CheckBox )
                {
                    ctrl.InternalChange = true;
                    var _checked = item.Value == "true" || item.Value == "on";
                    if ( _checked != ctrl.Checked )
                        ctrl.Checked = _checked;
                    ctrl.InternalChange = false;
                }
                else if ( ctrl is Ui.Form.Radio )
                {
                    var _checked = value == "true" || value == "on";
                    //( ctrl as Ui.Form.Radio ).InternalChange = true;
                    if ( _checked != ctrl.Checked )
                        ctrl.Checked = _checked;
                    //( ctrl as Ui.Form.CheckBox ).InternalChange = false;
                }
            }

            ( Base as Ui.Form.FormPanel ).RaiseFormPosted( e );
        }
    }
}